home *** CD-ROM | disk | FTP | other *** search
- * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
- * The C++ Answer Book */
- * Tony Hansen */
- * All rights reserved. */
- / _doprint(): low level function for doing
- / formatted output, to be invoked by the
- / v*printf() family of functions
- include <string.h>
-
- / endchar() returns TRUE for those format
- / characters which cause output.
- nt endchar(char c)
-
- switch (c)
- {
- case 'd': case 'i': case 'o': case 'u':
- case 'x': case 'X': case 'f': case 'e':
- case 'E': case 'g': case 'G': case 'c':
- case 's': case 'p': case 'n': case '%':
- case 0:
- return 1;
-
- default:
- return 0;
- }
-
-
- nt _doprint(ostream *out, const char *fmt, va_list vl)
-
- if (!fmt)
- return EOF;
-
- char *cfmt = new char[strlen(fmt)+1];
-
- while (*fmt)
- {
- char *buf = cfmt;
- int asterisks = 0;
- int shortarg = 0;
- int longarg = 0;
- char c;
-
- // loop looking for the beginning of a format
- while ((c = *buf++ = *fmt++) && (c != '%'))
- ;
-
- // loop looking for the end of the format
- if (c)
- while (!endchar(c = *buf++ = *fmt++))
- if (c == '*') asterisks++;
- else if (c == 'h') shortarg++;
- else if (c == 'l') longarg++;
-
- // polish off the buffer. leave fmt
- // pointing at the null if just past it.
- *buf = '\0';
- if (!c)
- fmt--;
-
- // pull off the width and precision
- int prec = 0, width = 0;
- switch (asterisks)
- {
- case 0: break;
- case 2: width = va_arg(vl, int); // NO BREAK
- case 1: prec = va_arg(vl, int); break;
- }
-
- / Declare a generic output routine for the type passed
- / on the stack and the type used for output. This
- / cannot be an inline since the parameters are types.
- define OUTPUT(parmtype, outtype) \
- do { \
- outtype val = va_arg(vl, parmtype); \
- switch (asterisks) \
- { \
- case 0: \
- (*out) << form(cfmt, val); break; \
- case 1: \
- (*out) << form(cfmt, prec, val); break; \
- case 2: \
- (*out) << form(cfmt,width,prec,val);break; \
- } \
- } while (0)
-
- // extract the value and output it
- switch (c)
- {
- // decimal variables
- case 'd': case 'i':
- if (longarg)
- OUTPUT(long, long);
-
- else if (shortarg)
- OUTPUT(short, int);
-
- else
- OUTPUT(int, int);
- break;
-
- // unsigned decimal variables
- case 'o': case 'u': case 'x': case 'X':
- if (longarg)
- OUTPUT(unsigned long, unsigned long);
-
- else if (shortarg)
- OUTPUT(unsigned short, unsigned int);
-
- else
- OUTPUT(unsigned int, unsigned int);
- break;
-
- // double variables
- case 'f': case 'e': case 'E':
- case 'g': case 'G':
- OUTPUT(double, double);
- break;
-
- // character variables
- case 'c':
- OUTPUT(unsigned char, int);
- break;
-
- // string variable
- case 's':
- OUTPUT(char*, char*);
- break;
-
- // nothing much here
- case '%': case 0:
- (*out) << form(cfmt);
- break;
- }
- }
-
- delete cfmt;
- return 1;
-
-